home *** CD-ROM | disk | FTP | other *** search
/ Aminet 35 / Aminet 35 (2000)(Schatztruhe)[!][Feb 2000].iso / Aminet / gfx / misc / gnuplot-src.lha / gnuplot-3.7.1src / gnuplot-3.7.1.lha / gnuplot-3.7.1 / term / imagen.trm < prev    next >
Encoding:
Text File  |  1998-12-14  |  22.4 KB  |  897 lines

  1. /*
  2.  * $Id: imagen.trm,v 1.7 1998/12/14 18:40:00 lhecking Exp $
  3.  */
  4.  
  5. /* GNUPLOT - imagen.trm */
  6.  
  7. /*[
  8.  * Copyright 1990 - 1993, 1998
  9.  *
  10.  * Permission to use, copy, and distribute this software and its
  11.  * documentation for any purpose with or without fee is hereby granted,
  12.  * provided that the above copyright notice appear in all copies and
  13.  * that both that copyright notice and this permission notice appear
  14.  * in supporting documentation.
  15.  *
  16.  * Permission to modify the software is granted, but not the right to
  17.  * distribute the complete modified source code.  Modifications are to
  18.  * be distributed as patches to the released version.  Permission to
  19.  * distribute binaries produced by compiling modified sources is granted,
  20.  * provided you
  21.  *   1. distribute the corresponding source modifications from the
  22.  *    released version in the form of a patch file along with the binaries,
  23.  *   2. add special version identification to distinguish your version
  24.  *    in addition to the base release version number,
  25.  *   3. provide your name and address as the primary contact for the
  26.  *    support of your modified version, and
  27.  *   4. retain our contact information in regard to use of the base
  28.  *    software.
  29.  * Permission to distribute the released version of the source code along
  30.  * with corresponding source modifications in the form of a patch file is
  31.  * granted with same provisions 2 through 4 for binary distributions.
  32.  *
  33.  * This software is provided "as is" without express or implied warranty
  34.  * to the extent permitted by applicable law.
  35. ]*/
  36.  
  37. /*
  38.  * This file is included by ../term.c.
  39.  *
  40.  * This terminal driver supports:
  41.  *   Imagen laser printers
  42.  *
  43.  * AUTHORS
  44.  *   Paul E. McKenney, David Kotz
  45.  *   Rewritten/extended by:
  46.  *    Hans Olav Eggestad
  47.  * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
  48.  * 
  49.  */
  50.  
  51. /*
  52.  * Original for direct Imagen output (but retaining many of the
  53.  * LaTeX extensions) by Paul E. McKenney, 1989.
  54.  * Further modified by David Kotz to fit into gnuplot 2.0.
  55.  * Information Science and Technology Division, SRI International,
  56.  * 333 Ravenswood Ave, Menlo Park, CA 94025.
  57.  * Mail to mckenney@sri.com.
  58.  */
  59. /*
  60.  * adapted to the new terminal layout by Stefan Bodewig (Dec. 1995)
  61.  */
  62.  
  63. #include "driver.h"
  64.  
  65. #ifdef TERM_REGISTER
  66. register_term(imagen)
  67. #endif
  68.  
  69. #ifdef TERM_PROTO
  70. TERM_PUBLIC void IMAGEN_init __PROTO((void));
  71. TERM_PUBLIC void IMAGEN_graphics __PROTO((void));
  72. TERM_PUBLIC void IMAGEN_options __PROTO((void));
  73. TERM_PUBLIC void IMAGEN_text __PROTO((void));
  74. TERM_PUBLIC void IMAGEN_linetype __PROTO((int lt));
  75. TERM_PUBLIC void IMAGEN_move __PROTO((unsigned int x, unsigned int y));
  76. TERM_PUBLIC void IMAGEN_vector __PROTO((unsigned int ux, unsigned int uy));
  77. TERM_PUBLIC int IMAGEN_text_angle __PROTO((int ang));
  78. TERM_PUBLIC int IMAGEN_justify_text __PROTO((enum JUSTIFY mode));
  79. TERM_PUBLIC void IMAGEN_put_text __PROTO((unsigned int x, unsigned int y, char str[]));
  80. TERM_PUBLIC void IMAGEN_reset __PROTO((void));
  81. #define IMAGEN_PTS_PER_INCH (300)
  82. #define IMAGEN_XMAX (IMAGEN_PTS_PER_INCH * 11)    /* 10.0 inches */
  83. #define IMAGEN_YMAX (IMAGEN_PTS_PER_INCH * 78 / 10)    /* 7.5 inches */
  84. #define IMAGEN_HTIC (20)
  85. #define IMAGEN_VTIC (20)
  86. #define IMAGEN_VCHAR (IMAGEN_FONTSIZE*5)
  87. #define IMAGEN_HCHAR (IMAGEN_VCHAR/2)
  88. #endif /* TERM_PROTO */
  89.  
  90. #ifndef TERM_PROTO_ONLY
  91. #ifdef TERM_BODY
  92.  
  93. static void IM_page __PROTO((void));
  94. static void IMAGEN_draw_path __PROTO((void));
  95. static void IMAGEN_setpos __PROTO((int ux, int uy));
  96. static unsigned char *IMAGEN_cvts __PROTO((unsigned char *str, int *width, int *height));
  97. static void IMAGEN_putwd __PROTO((unsigned int w));
  98. static void IMAGEN_createfamily __PROTO((char *c, int sz));
  99. static void IMAGEN_setfont __PROTO((int sz));
  100. void IMP_set_draw_pattern __PROTO((int pattern, int sz));
  101. void IMAGEN_mapsinit __PROTO((void));
  102. void IMAGEN_createmap __PROTO((int name, unsigned short *map));
  103.  
  104.  
  105. /*
  106. #ifndef __malloc_h
  107. #include <malloc.h>
  108. #endif
  109. */
  110. #include "impcodes.h"
  111.  
  112. /* default is landscape */
  113. #define IMAGEN_A4_H  (IMAGEN_PTS_PER_INCH * 83 / 10)
  114. #define IMAGEN_A4_W  (IMAGEN_PTS_PER_INCH * 116 / 10)
  115.  
  116. /* width in current orientation */
  117. static int IMAGEN_Xmax = IMAGEN_XMAX;
  118. static int IMAGEN_Ymax = IMAGEN_YMAX;
  119.  
  120. #define IMAGEN_FONTSIZE 12
  121. #define IMAGEN_FONT "cour"
  122.  
  123.  
  124. unsigned short IMP_gmap[128];
  125. unsigned char IMP_chmap[256];
  126.  
  127. static int IMAGEN_page_h = IMAGEN_A4_H;
  128. static int IMAGEN_page_w = IMAGEN_A4_W;
  129. static int IM_win_horiz = 1;
  130. static int IM_win_verti = 1;
  131. static int IM_plot_nr = 0;
  132.  
  133. static int IMAGEN_fontsize = IMAGEN_FONTSIZE;
  134. static int IMAGEN_familytable[36];
  135. static int IMAGEN_orgX;        /* absolute-pixel-ORIgin of graph page. */
  136. static int IMAGEN_orgY;
  137. static int IMAGEN_orgx;        /* absolute-pixel-ORIgin of current graph. */
  138. static int IMAGEN_orgy;
  139. static int IMAGEN_posx;        /* current drawing position (lines).    */
  140. static int IMAGEN_posy;
  141. /* static int IMAGEN_inplot; */
  142. static int IMAGEN_xmax = IMAGEN_XMAX;    /* width of graph in pixels.    */
  143. static int IMAGEN_ymax = IMAGEN_YMAX;    /* height of graph in pixels.   */
  144. static int IMAGEN_winx = IMAGEN_XMAX;    /* width of window in pixels.   */
  145. static int IMAGEN_winy = IMAGEN_YMAX;    /* height of window in pixels.  */
  146. static int IMAGEN_hchar;    /* Height of CHAR in current font.      */
  147. static int IMAGEN_wchar;    /* Width of CHAR in current font.       */
  148. static int IMAGEN_blofs;    /* BaseLine OFfSet from bounding box.   */
  149. static int IMAGEN_angle = -1;    /* 0 for horizontal text, 1 for vertical */
  150. static int IMAGEN_portrait;    /* 0 for landscape */
  151. static enum JUSTIFY IMAGEN_justify = LEFT;    /* left/center/right */
  152.  
  153. #define STOREPATH 100
  154. unsigned int IM_xvector[STOREPATH];    /* draw path vector of x values */
  155. unsigned int IM_yvector[STOREPATH];    /* draw path vector of y values */
  156. unsigned int IM_veclen;        /* length of allocated path vector */
  157. unsigned int IM_vecpos = 0;    /* current pos in vector */
  158.  
  159. /* char IMPdrpattern[10][10] = { {0}, {30,10,0}, {0}, {10,30,0}, {2,20,0}, 
  160.     {20,10,0}, {30,20,10,20,0}, {30,20,4,10,10,10,4,20,0}, {40,20,0}, {30,15,4,15,0}
  161. };
  162. */
  163.  
  164. char IMPdrpattern[10][10] =
  165. {
  166. /* -2 */ {0},
  167. /* -1 */ {1, 8, 0},
  168. /*  0 */ {0},
  169. /*  1 */ {16, 4, 0},
  170. /*  2 */ {3, 8, 0},
  171. /*  3 */ {8, 8, 0},
  172. /*  4 */ {16, 6, 3, 6, 0},
  173. /*  5 */ {16, 6, 8, 6, 0},
  174. /*  6 */ {16, 4, 1, 4, 8, 4, 1, 4, 0},
  175. /*  7 */ {16, 4, 1, 8, 1, 4, 0}
  176. };
  177.  
  178. TERM_PUBLIC void IMAGEN_init()
  179. {
  180.     register struct termentry *t = term;
  181.  
  182. /* char font[10];   *//* font name */
  183.  
  184.     IMAGEN_posx = IMAGEN_posy = 0;
  185.  
  186.     IMAGEN_orgX = (IMAGEN_page_w - IMAGEN_Xmax) / 2;
  187.     IMAGEN_orgY = (IMAGEN_page_h - IMAGEN_Ymax) / 2;
  188.  
  189.     IMAGEN_xmax = IMAGEN_winx = (int) (IMAGEN_Xmax / IM_win_horiz);
  190.     IMAGEN_ymax = IMAGEN_winy = (int) (IMAGEN_Ymax / IM_win_verti);
  191.  
  192.     t->xmax = (unsigned int) (IMAGEN_xmax);
  193.     t->ymax = (unsigned int) (IMAGEN_ymax);
  194.  
  195.     fputs("@document(language impress, paper a4)", gpoutfile);
  196.  
  197.     if (IMAGEN_portrait) {
  198.     putc(imP_SET_ABS_V, gpoutfile);
  199.     IMAGEN_putwd(3520);
  200.     }
  201.     putc(imP_SET_HV_SYSTEM, gpoutfile);
  202.     putc(((IMAGEN_portrait ? 3 : 0) << 5) | (3 << 3) | (IMAGEN_portrait ? 0 : 5), gpoutfile);
  203.  
  204.     /* sprintf(font, "cour%02d", IMAGEN_FONTSIZE); */
  205.     IMAGEN_mapsinit();
  206.     IMAGEN_createmap(1, IMP_gmap);
  207.     /* IMAGEN_createfamily(font, IMAGEN_FONTSIZE); */
  208.     IMAGEN_setfont(IMAGEN_fontsize);
  209.  
  210.     IMAGEN_text_angle(0);
  211.  
  212.     putc(imP_SET_ABS_H, gpoutfile);
  213.     IMAGEN_putwd(0);
  214.     putc(imP_SET_ABS_V, gpoutfile);
  215.     IMAGEN_putwd(0);
  216.  
  217.     IMAGEN_linetype(-1);
  218.     /*
  219.        if ((IM_xvector = (unsigned int *) malloc(STOREPATH*sizeof(int))) == NULL) {
  220.        fputs("Imagendriver: Unable to allocate memory for draw path\n", stderr);
  221.        exit(1);
  222.        }
  223.        if ((IM_yvector = (unsigned int *) malloc(STOREPATH*sizeof(int))) == NULL) {
  224.        fputs("Imagendriver: Unable to allocate memory for draw path\n", stderr);
  225.        exit(1);
  226.        }
  227.      */
  228.     IM_veclen = STOREPATH;
  229.     IM_vecpos = 0;
  230. }
  231.  
  232. static void IM_page()
  233. {
  234.     if (IM_vecpos) {
  235.     /* fprintf(stderr,"graphics, draw path\n"); */
  236.     IMAGEN_draw_path();
  237.     }
  238.     putc(imP_ENDPAGE, gpoutfile);
  239. }
  240.  
  241. TERM_PUBLIC void IMAGEN_graphics()
  242. {
  243.     int tmpx, tmpy;
  244. /*    int xoff, yoff; */
  245.  
  246.     if (IM_vecpos) {
  247.     /* fprintf(stderr,"graphics, draw path\n"); */
  248.     IMAGEN_draw_path();
  249.     }
  250.     if (IM_plot_nr >= (IM_win_horiz * IM_win_verti)) {
  251.     IM_page();
  252.     IM_plot_nr = 0;
  253.     }
  254.     IM_plot_nr++;
  255.     tmpx = IMAGEN_orgX + ((IM_plot_nr - 1) % IM_win_horiz) * IMAGEN_winx;
  256.     tmpy = IMAGEN_orgY + ((IM_win_verti - 1) - (int) ((IM_plot_nr - 1) / IM_win_horiz)) * IMAGEN_winy;
  257.     IMAGEN_orgx = tmpx + (int) ((IMAGEN_winx - IMAGEN_xmax) / 2);
  258.     IMAGEN_orgy = tmpy + (int) ((IMAGEN_winy - IMAGEN_ymax) / 2);
  259. }
  260.  
  261. TERM_PUBLIC void IMAGEN_options()
  262. {
  263.     struct value a;
  264.  
  265.     while (!END_OF_COMMAND) {
  266.     if (almost_equals(c_token, "p$ortrait")) {
  267.         IMAGEN_portrait = TRUE;
  268.         IMAGEN_page_h = IMAGEN_A4_W;
  269.         IMAGEN_page_w = IMAGEN_A4_H;
  270.         IMAGEN_Xmax = IMAGEN_YMAX;
  271.         IMAGEN_Ymax = IMAGEN_XMAX;
  272.         c_token++;
  273.     } else if (almost_equals(c_token, "l$andscape")) {
  274.         IMAGEN_portrait = FALSE;
  275.         c_token++;
  276.     } else if (equals(c_token, "[")) {    /* windows spesified */
  277.         c_token++;
  278.         /* if (IM_plot_nr>1) */
  279.         if (equals(c_token, "]")) {
  280.         IM_page();
  281.         c_token++;
  282.         continue;
  283.         }
  284.         if (END_OF_COMMAND) {
  285.         int_error("no. windows: [horizontal,vertical] expected", c_token);
  286.         } else if (!equals(c_token, ",")) {
  287.         IM_win_horiz = (int) real(const_express(&a));
  288.         }
  289.         if (!equals(c_token, ","))
  290.         int_error("',' expected", c_token);
  291.         c_token++;
  292.         if (!equals(c_token, "]")) {
  293.         IM_win_verti = (int) real(const_express(&a));
  294.         }
  295.         if (!equals(c_token, "]"))
  296.         int_error("expecting ']'", c_token);
  297.         c_token++;
  298.     } else {
  299.         /* We have font size specified */
  300.         IMAGEN_fontsize = (int) real(const_express(&a));
  301.         if (IMAGEN_fontsize < 8)
  302.         IMAGEN_fontsize = 8;
  303.         if (IMAGEN_fontsize > 15)
  304.         IMAGEN_fontsize = 15;
  305.     }
  306.     }
  307.     sprintf(term_options, "%d %s [%1d,%1d]", IMAGEN_fontsize, (IMAGEN_portrait) ? "portrait" :
  308.         "landscape", IM_win_horiz, IM_win_verti);
  309. }
  310.  
  311.  
  312. TERM_PUBLIC void IMAGEN_text()
  313. {
  314. }
  315.  
  316.  
  317. #define DRAW_PATTERNS 6
  318.  
  319.  
  320. TERM_PUBLIC void IMAGEN_linetype(lt)
  321. int lt;
  322. {
  323.     static int lastlinetype = -10;
  324.     int pen /*, pattern */ ;
  325.  
  326.     if (IM_vecpos) {
  327.     /* fprintf(stderr,"move, draw path\n"); */
  328.     IMAGEN_draw_path();
  329.     }
  330. /* -2: axis
  331.    -1: border
  332.     0: arrow
  333.     1-7: graph
  334. */
  335.     if (lt == -2) {
  336.     pen = 4;
  337.     } else {
  338.     pen = (int) (lt / 8) * 2;
  339.     if (pen <= 0)
  340.         pen = 1;
  341.     }
  342.     lt = (lt % 8) + 2;
  343.  
  344.     if (lastlinetype == lt)
  345.     return;
  346.  
  347.     lastlinetype = lt;
  348.  
  349.     putc(imP_SET_PEN, gpoutfile);
  350.     putc(pen, gpoutfile);
  351.     IMP_set_draw_pattern(lt, pen);
  352. }
  353.  
  354.  
  355. TERM_PUBLIC void IMAGEN_move(x, y)
  356. unsigned int x, y;
  357. {
  358.     if (IM_vecpos) {
  359.     /* fprintf(stderr,"move, draw path\n"); */
  360.     IMAGEN_draw_path();
  361.     }
  362.     IM_xvector[0] = x + IMAGEN_orgx;
  363.     IM_yvector[0] = y + IMAGEN_orgy;
  364.     /* fprintf(stderr,"Ny vector: startpos: %1d %1d\n",IM_xvector[0],IM_yvector[0]); */
  365.     IM_vecpos = 1;
  366.     /* 
  367.        IMAGEN_posx = x;
  368.        IMAGEN_posy = y;
  369.      */
  370. }
  371.  
  372. TERM_PUBLIC void IMAGEN_vector(ux, uy)
  373. unsigned int ux, uy;
  374. {
  375.     /* void IMAGEN_draw_path(); */
  376.  
  377.     /* Store path. */
  378.     IM_xvector[IM_vecpos] = ux + IMAGEN_orgx;
  379.     IM_yvector[IM_vecpos] = uy + IMAGEN_orgy;
  380.     /* fprintf(stderr,"Ny node: nr: %1d; %1d %1d\n",IM_vecpos,IM_xvector[IM_vecpos],IM_yvector[IM_vecpos]);  */
  381.     IM_vecpos++;
  382.     if (IM_vecpos >= IM_veclen) {
  383.     IMAGEN_draw_path();
  384.     IM_xvector[0] = ux + IMAGEN_orgx;
  385.     IM_yvector[0] = uy + IMAGEN_orgy;
  386.     IM_vecpos = 1;
  387.     }
  388. }
  389.  
  390. static void IMAGEN_draw_path()
  391. {
  392. /*    unsigned int pos; */
  393.     register int i;
  394.  
  395.     putc(imP_CREATE_PATH, gpoutfile);
  396.     IMAGEN_putwd(IM_vecpos);
  397.     for (i = 0; i < IM_vecpos; i++) {
  398.     /*
  399.        IMAGEN_putwd(IM_xvector[i] + IMAGEN_orgx);
  400.        IMAGEN_putwd(IM_yvector[i] + IMAGEN_orgy);
  401.      */
  402.     IMAGEN_putwd(IM_xvector[i]);
  403.     IMAGEN_putwd(IM_yvector[i]);
  404.     }
  405.     IM_vecpos = 0;
  406.     /* Draw path with black pen. */
  407.  
  408.     putc(imP_DRAW_PATH, gpoutfile);
  409.     putc(15, gpoutfile);
  410.  
  411.     /* Set current position to end of line. */
  412.  
  413.     /* IMAGEN_move(ux, uy); */
  414. }
  415.  
  416. static void IMAGEN_setpos(ux, uy)
  417. int ux, uy;
  418. {
  419.     /* Set x and y position (for text), also set beginning-of-line. */
  420.  
  421.     putc(imP_SET_ABS_H, gpoutfile);
  422.     IMAGEN_putwd(ux + IMAGEN_orgx);
  423.     putc(imP_SET_ABS_V, gpoutfile);
  424.     IMAGEN_putwd(uy + IMAGEN_orgy);
  425.     putc(imP_SET_BOL, gpoutfile);
  426.     if (IMAGEN_angle == 1)
  427.     IMAGEN_putwd(uy + IMAGEN_orgx);        /* vertical */
  428.     else
  429.     IMAGEN_putwd(ux + IMAGEN_orgx);        /* horizontal */
  430. }
  431.  
  432. TERM_PUBLIC int IMAGEN_text_angle(ang)
  433. int ang;
  434. {
  435.  
  436.     if (IM_vecpos) {
  437.     /* fprintf(stderr,"text_angle, draw path\n"); */
  438.     IMAGEN_draw_path();
  439.     }
  440.     if (IMAGEN_angle != ang) {
  441.     IMAGEN_angle = ang;    /* record for later use */
  442.     putc(imP_SET_ADV_DIRS, gpoutfile);
  443.     putc(ang == 0 ? 0 : 7, gpoutfile);    /* 0=>horiz : 7=>vert */
  444.     }
  445.     return (TRUE);
  446. }
  447.  
  448. TERM_PUBLIC int IMAGEN_justify_text(mode)
  449. enum JUSTIFY mode;
  450. {
  451.     if (IM_vecpos) {
  452.     /* fprintf(stderr,"justify_text, draw path\n"); */
  453.     IMAGEN_draw_path();
  454.     }
  455.     IMAGEN_justify = mode;
  456.     return (TRUE);
  457. }
  458.  
  459. static unsigned char *IMAGEN_cvts(str, width, height)
  460. unsigned char *str;
  461. int *width;
  462. int *height;
  463. {
  464.     unsigned char *cp1;
  465.     unsigned char *cp2;
  466.     static unsigned char *buf = NULL;
  467.     int h;
  468.     int maxw;
  469.     int w;
  470.  
  471.     /* Free up old buffer, if there is one, get a new one.  Since       */
  472.     /* all transformations shorten the string, get a buffer that is     */
  473.     /* the same size as the input string.                               */
  474.  
  475.     if (buf != NULL)
  476.     (void) free(buf);
  477.     buf = (unsigned char *) gp_alloc(strlen((char *) str), "converted label string");
  478.  
  479.     /* Do the transformations. */
  480.  
  481.     cp1 = str;
  482.     cp2 = buf;
  483.     h = 1;
  484.     maxw = 0;
  485.     w = 0;
  486.     while (strlen((char *) cp1) > 0) {
  487.     switch (*cp1) {
  488.     case ' ':        /* Space character. */
  489.         *cp2++ = imP_SP;
  490.         w++;
  491.         break;
  492.  
  493.     case '\\':        /* Escape sequence. */
  494.         if (*++cp1 == '\\') {
  495.         /* Begin new line. */
  496.         h++;
  497.         if (w > maxw)
  498.             maxw = w;
  499.         w = 0;
  500.         *cp2++ = '\n';
  501.         /* *cp2++ = imP_CRLF; */
  502.         break;
  503.         }
  504.         /* Fall through to just copy next char out. */
  505.  
  506.     default:
  507.         /* *cp2++ = *cp1; */
  508.         *cp2++ = IMP_chmap[*cp1];
  509.         w++;
  510.         break;
  511.     }
  512.     cp1++;
  513.     }
  514.  
  515.     *cp2++ = '\n';
  516.     *cp2 = '\0';
  517.     if (w > maxw)
  518.     maxw = w;
  519.  
  520.     if (height != NULL)
  521.     *height = IMAGEN_angle ?
  522.         IMAGEN_wchar * maxw :
  523.         IMAGEN_hchar * h;
  524.     if (width != NULL)
  525.     *width = IMAGEN_angle ?
  526.         IMAGEN_hchar * h :
  527.         IMAGEN_wchar * maxw;
  528.     return (buf);
  529. }
  530.  
  531. TERM_PUBLIC void IMAGEN_put_text(x, y, str)
  532. unsigned int x, y;        /* reference point of string */
  533. char str[];            /* the text */
  534. {
  535.     unsigned char *cvstr, *p;
  536.     int height;
  537.     int width;
  538.     int sx, sy;
  539.  
  540.     if (IM_vecpos) {
  541.     /* fprintf(stderr,"put_text, draw path\n"); */
  542.     IMAGEN_draw_path();
  543.     }
  544.     cvstr = IMAGEN_cvts((unsigned char *) str, &width, &height);
  545.  
  546.     if (IMAGEN_angle) {        /* vertical */
  547.     /* x += IMAGEN_hchar; */
  548.     x -= width / 2 - IMAGEN_hchar;
  549.     /* y -= height/2; */
  550.     } else            /* horizontal */
  551.     y += height / 2 - IMAGEN_hchar;
  552.  
  553.     while ((p = (unsigned char *) strchr((char *) cvstr, '\n'))) {
  554.     *p = '\0';
  555.     sx = x;
  556.     sy = y;
  557.     if (IMAGEN_angle)
  558.         sx = x - IMAGEN_blofs;
  559.     else
  560.         sy = y + IMAGEN_blofs;
  561.  
  562.     width = strlen((char *) cvstr) * IMAGEN_wchar;
  563.  
  564.     switch (IMAGEN_justify) {
  565.     case LEFT:
  566.         break;
  567.     case CENTRE:
  568.         if (IMAGEN_angle) {
  569.         sy = y - width / 2;
  570.         } else {
  571.         sx = x - width / 2;
  572.         }
  573.         break;
  574.         /*x -= width/2; break; */
  575.     case RIGHT:
  576.         if (IMAGEN_angle) {
  577.         sy = y - width;
  578.         } else {
  579.         sx = x - width;
  580.         }
  581.         break;
  582.         /* x -= width; break; */
  583.     }
  584.  
  585.     IMAGEN_setpos(sx, sy);
  586.     fputs((char *) cvstr, gpoutfile);
  587.     cvstr = ++p;
  588.     if (IMAGEN_angle) {    /* vertical */
  589.         x += IMAGEN_hchar;
  590.     } else {
  591.         y -= IMAGEN_hchar;
  592.     }
  593.  
  594.     }
  595. }
  596.  
  597. TERM_PUBLIC void IMAGEN_reset()
  598. {
  599.     if (IM_vecpos) {
  600.     /* fprintf(stderr,"reset, draw path\n"); */
  601.     IMAGEN_draw_path();
  602.     }
  603.     putc(imP_EOF, gpoutfile);
  604. }
  605.  
  606. static void IMAGEN_putwd(w)
  607. unsigned int w;
  608. {
  609.     /* fprintf(stderr,"%1u\n",w); */
  610.     putc(w >> 8, gpoutfile);
  611.     putc(w, gpoutfile);
  612. }
  613.  
  614. static void IMAGEN_createfamily(c, sz)
  615. char *c;
  616. int sz;
  617. {
  618.  
  619.     putc(imP_CREATE_FAMILY_TABLE, gpoutfile);
  620.     putc(sz, gpoutfile);
  621.     putc(1, gpoutfile);
  622.     putc(1, gpoutfile);
  623.     /* putc(0, gpoutfile); */
  624.     fputs(c, gpoutfile);
  625.     putc(0, gpoutfile);
  626. }
  627.  
  628. static void IMAGEN_setfont(sz)
  629. int sz;
  630. {
  631.     char font[20];
  632.  
  633.     if (!IMAGEN_familytable[sz]) {
  634.     sprintf(font, "%s%02d", IMAGEN_FONT, sz);
  635.     IMAGEN_createfamily(font, sz);
  636.     IMAGEN_familytable[sz] = sz;
  637.     }
  638.     IMAGEN_hchar = sz * 5;
  639.     IMAGEN_wchar = IMAGEN_hchar / 2;
  640.     IMAGEN_blofs = IMAGEN_hchar / 3;
  641.     term->v_char = IMAGEN_hchar;
  642.     term->h_char = IMAGEN_wchar;
  643.     putc(imP_SET_FAMILY, gpoutfile);
  644.     putc(sz, gpoutfile);
  645.     putc(imP_SET_SP, gpoutfile);
  646.     IMAGEN_putwd(IMAGEN_wchar);
  647.     putc(imP_SET_IL, gpoutfile);
  648.     IMAGEN_putwd(IMAGEN_hchar);
  649. }
  650.  
  651. void IMP_set_draw_pattern(pattern, sz)
  652. int pattern, sz;
  653. {
  654.     int i /*,j */ ;
  655.     putc(imP_SET_DRAW_PATTERN, gpoutfile);
  656.     putc(0, gpoutfile);
  657.     putc(imP_SET_DRAW_PATTERN, gpoutfile);
  658.     /* if ( strlen(IMPdrpattern[pattern]) == 1 ) {
  659.        putc(type,gpoutfile);
  660.        return;
  661.        } */
  662.     putc(strlen(IMPdrpattern[pattern]), gpoutfile);
  663.     for (i = 0; i < strlen(IMPdrpattern[pattern]); i++) {
  664.     IMAGEN_putwd(IMPdrpattern[pattern][i] * sz);
  665.     }
  666. }
  667.  
  668.  
  669. void IMAGEN_mapsinit()
  670. {
  671.  
  672.     register int i /*, j */ ;
  673.  
  674.     for (i = 32; i < 127; i++) {
  675.     IMP_gmap[i] = i;
  676.     }
  677.     IMP_gmap[1] = 225;
  678.     IMP_gmap[2] = 233;
  679.     IMP_gmap[3] = 61736;
  680.     IMP_gmap[4] = 241;
  681.     IMP_gmap[5] = 249;
  682.     IMP_gmap[6] = 61864;
  683.     IMP_gmap[7] = 162;
  684.     IMP_gmap[8] = 163;
  685.     IMP_gmap[9] = 164;
  686.     IMP_gmap[10] = 165;
  687.     IMP_gmap[11] = 167;
  688.     IMP_gmap[12] = 171;
  689.     IMP_gmap[13] = 182;
  690.     IMP_gmap[14] = 61346;
  691.     IMP_gmap[15] = 191;
  692.     IMP_gmap[16] = 187;
  693.     IMP_gmap[17] = 188;
  694.     IMP_gmap[18] = 189;
  695.     IMP_gmap[19] = 190;
  696.     IMP_gmap[20] = 210;
  697.     IMP_gmap[21] = 211;
  698.     IMP_gmap[22] = 251;
  699.     IMP_gmap[23] = 61232;
  700.     IMP_gmap[24] = 212;
  701.     IMP_gmap[25] = 137;
  702.     IMP_gmap[26] = 176;
  703.     IMP_gmap[27] = 161;
  704.     IMP_gmap[28] = 139;
  705.     IMP_gmap[29] = 133;
  706.     IMP_gmap[30] = 140;
  707.     IMP_gmap[31] = 61249;
  708.     IMP_gmap[32] = 8738;
  709.     IMP_gmap[34] = 186;
  710.     IMP_gmap[36] = 164;
  711.     IMP_gmap[39] = 185;
  712.     IMP_gmap[127] = 61286;
  713.  
  714.     /* for (i=1;i<127;i++) fprintf(stderr,"%d -> %d\n",i,IMP_gmap[i]); */
  715.  
  716.     for (i = 32; i <= 127; i++) {
  717.     IMP_chmap[i] = i;
  718.     }
  719.     for (i = 128; i <= 255; i++) {
  720.     IMP_chmap[i] = 128;    /* first map all non printable chars to SPACE */
  721.     }
  722.  
  723.     IMP_chmap[161] = 27;
  724.     IMP_chmap[162] = 7;
  725.     IMP_chmap[163] = 8;
  726.     IMP_chmap[164] = 120;
  727.     IMP_chmap[165] = 10;
  728.     IMP_chmap[166] = 124;
  729.     IMP_chmap[167] = 11;
  730.     IMP_chmap[168] = 25;
  731.     IMP_chmap[169] = 21;
  732.     IMP_chmap[170] = 45;
  733.     IMP_chmap[171] = 12;
  734.     IMP_chmap[172] = 83;
  735.     IMP_chmap[173] = 45;
  736.     IMP_chmap[174] = 20;
  737.     IMP_chmap[175] = 126;
  738.     IMP_chmap[176] = 26;
  739.     IMP_chmap[177] = 12;
  740.     IMP_chmap[178] = 1;
  741.     IMP_chmap[179] = 2;
  742.     IMP_chmap[180] = 29;
  743.     IMP_chmap[181] = 52;
  744.     IMP_chmap[182] = 13;
  745.     IMP_chmap[183] = 5;
  746.     IMP_chmap[184] = 28;
  747.     IMP_chmap[185] = 3;
  748.     IMP_chmap[186] = 45;
  749.     IMP_chmap[187] = 16;
  750.     IMP_chmap[188] = 17;
  751.     IMP_chmap[189] = 18;
  752.     IMP_chmap[190] = 19;
  753.     IMP_chmap[191] = 15;
  754.     IMP_chmap[192] = 65;
  755.     IMP_chmap[193] = 65;
  756.     IMP_chmap[194] = 65;
  757.     IMP_chmap[195] = 65;
  758.     IMP_chmap[196] = 65;
  759.     IMP_chmap[197] = 3;
  760.     IMP_chmap[198] = 1;
  761.     IMP_chmap[199] = 67;
  762.     IMP_chmap[200] = 69;
  763.     IMP_chmap[201] = 69;
  764.     IMP_chmap[202] = 69;
  765.     IMP_chmap[203] = 69;
  766.     IMP_chmap[204] = 73;
  767.     IMP_chmap[205] = 73;
  768.     IMP_chmap[206] = 73;
  769.     IMP_chmap[207] = 73;
  770.     IMP_chmap[208] = 68;
  771.     IMP_chmap[209] = 78;
  772.     IMP_chmap[210] = 79;
  773.     IMP_chmap[211] = 79;
  774.     IMP_chmap[212] = 79;
  775.     IMP_chmap[213] = 79;
  776.     IMP_chmap[214] = 79;
  777.     IMP_chmap[215] = 13;
  778.     IMP_chmap[216] = 2;
  779.     IMP_chmap[217] = 85;
  780.     IMP_chmap[218] = 85;
  781.     IMP_chmap[219] = 85;
  782.     IMP_chmap[220] = 85;
  783.     IMP_chmap[221] = 89;
  784.     IMP_chmap[222] = 32;
  785.     IMP_chmap[223] = 22;
  786.     IMP_chmap[224] = 97;
  787.     IMP_chmap[225] = 97;
  788.     IMP_chmap[226] = 97;
  789.     IMP_chmap[227] = 97;
  790.     IMP_chmap[228] = 97;
  791.     IMP_chmap[229] = 6;
  792.     IMP_chmap[230] = 4;
  793.     IMP_chmap[231] = 99;
  794.     IMP_chmap[232] = 101;
  795.     IMP_chmap[233] = 101;
  796.     IMP_chmap[234] = 101;
  797.     IMP_chmap[235] = 101;
  798.     IMP_chmap[236] = 105;
  799.     IMP_chmap[237] = 105;
  800.     IMP_chmap[238] = 105;
  801.     IMP_chmap[239] = 105;
  802.     IMP_chmap[240] = 100;
  803.     IMP_chmap[241] = 110;
  804.     IMP_chmap[242] = 111;
  805.     IMP_chmap[243] = 111;
  806.     IMP_chmap[244] = 111;
  807.     IMP_chmap[245] = 111;
  808.     IMP_chmap[246] = 111;
  809.     IMP_chmap[247] = 10;
  810.     IMP_chmap[248] = 5;
  811.     IMP_chmap[249] = 117;
  812.     IMP_chmap[250] = 117;
  813.     IMP_chmap[251] = 117;
  814.     IMP_chmap[252] = 117;
  815.     IMP_chmap[253] = 121;
  816.     IMP_chmap[254] = 32;
  817.     IMP_chmap[255] = 121;
  818. }
  819.  
  820. void IMAGEN_createmap(name, map)
  821. unsigned short *map;
  822. int name;
  823. {
  824.     register int i, j;
  825.     unsigned char s[4], *p;
  826.  
  827.     p = s;
  828.     *p++ = imP_CREATE_MAP;
  829.     *p++ = name;
  830.     j = 0;
  831.     for (i = 0; i < 127; i++) {
  832.     if (map[i])
  833.         j++;
  834.     }
  835.     *p = j;
  836.     for (i = 0; i < 3; i++)
  837.     putc(s[i], gpoutfile);
  838.  
  839.     s[3] = 1;
  840.     for (j = 0; j < 127; j++) {
  841.     if (map[j]) {
  842.         p = s;
  843.         *p++ = j;
  844.         *p++ = map[j] >> 8;
  845.         *p = map[j] & 255;
  846.         for (i = 0; i < 4; i++)
  847.         putc(s[i], gpoutfile);
  848.     }
  849.     }
  850. }
  851.  
  852. #endif /* TERM_BODY */
  853.  
  854. #ifdef TERM_TABLE
  855.  
  856. TERM_TABLE_START(imagen_driver)
  857.     "imagen", "Imagen laser printer",
  858.     IMAGEN_XMAX, IMAGEN_YMAX, IMAGEN_VCHAR, IMAGEN_HCHAR,
  859.     IMAGEN_VTIC, IMAGEN_HTIC, IMAGEN_options, IMAGEN_init, IMAGEN_reset,
  860.     IMAGEN_text, null_scale, IMAGEN_graphics, IMAGEN_move,
  861.     IMAGEN_vector, IMAGEN_linetype, IMAGEN_put_text, IMAGEN_text_angle,
  862.     IMAGEN_justify_text, line_and_point, do_arrow, set_font_null
  863. TERM_TABLE_END(imagen_driver)
  864.  
  865. #undef LAST_TERM
  866. #define LAST_TERM imagen_driver
  867.  
  868. #endif /* TERM_TABLE */
  869. #endif /* TERM_PROTO_ONLY */
  870.  
  871. #ifdef TERM_HELP
  872. START_HELP(imagen)
  873. "1 imagen",
  874. "?commands set terminal imagen",
  875. "?set terminal imagen",
  876. "?set term imagen",
  877. "?terminal imagen",
  878. "?term imagen",
  879. "?imagen",
  880. " The `imagen` terminal driver supports Imagen laser printers.  It is capable",
  881. " of placing multiple graphs on a single page.",
  882. "",
  883. " Syntax:",
  884. "       set terminal imagen {<fontsize>} {portrait | landscape}",
  885. "                           {[<horiz>,<vert>]}",
  886. "",
  887. " where `fontsize` defaults to 12 points and the layout defaults to `landscape`.",
  888. " `<horiz>` and `<vert>` are the number of graphs in the horizontal and",
  889. " vertical directions; these default to unity.",
  890. "",
  891. " Example:",
  892. "       set terminal imagen portrait [2,3]",
  893. "",
  894. " puts six graphs on the page in three rows of two in portrait orientation."
  895. END_HELP(imagen)
  896. #endif
  897.